package primegen.candidate.generation.impl



import java.util.concurrent.Callable;

/**
 * This generates a list of prime numbers
 *  
 * @author kurtg
 */
class BaseGenerator implements Callable<ArrayList<Long>> {

	def ArrayList<Long> seedPrimes

	def primeMap;

	long from;
	long to;

	/**
	 * 
	 * @param seedPrimes - exhaustive list of lower primes used to filter candidates
	 * @param from
	 * @param to
	 */
	BaseGenerator(final ArrayList<Long> seedPrimes, long from, long to) {
		this.seedPrimes = seedPrimes

		// make sure we start at an odd
		this.from = (from & 1) ? from : from+1
		this.to = to;
	}

	/**
	 * @return  List of possible candidates
	 */
	ArrayList<Long> call() {
		// init map
		primeMap = new HashMap()
		seedPrimes.each {
			long value = from % it
			primeMap.put(it, new Nut(value))
		}
		primeMap.remove(2L)

		def candidates = new ArrayList<Long>()
		for (long l = from; l <= to; l += 2) {
			def possiblePrime = true
			primeMap.each { key, nut ->
				if (nut.value == 0) {
					possiblePrime = false
				}

				if ((nut.value += 2) >= key) {
					nut.value -= key
				}
			}

			if (possiblePrime) {
				candidates.add l
				println l
			}
		}

		return candidates;
	}

}


// just wrap long, so we aren't constantly doing puts on the hashmap.
class Nut {
	long value
	
	Nut(long value) {
		this.value = value
	}
}
